package cn.agiledata.bank.transaction.exception;

import java.io.IOException;

import cn.agiledata.bank.common.util.StringUtil;
import cn.agiledata.bank.hibernateBean.Account;
import cn.agiledata.bank.hibernateBean.AccountLimit;
import com.vnv.infrastructure.exception.IPBAppException;

public class TransactionException extends IPBAppException {

    /**
     * 没有操作权限异常
     */
    public static final TransactionException NO_PERMISSION = new TransactionException(
            "error.transaction.no_permission");

    /**
     * 无效金额异常
     */
    public static final TransactionException INVALID_AMOUT = new TransactionException(
            "error.invalid_amount");

    /**
     * 交易操作失败异常
     */
    public static final TransactionException TRANSACTION_FAILED = new TransactionException(
            "error.transaction.failed");

    /**
     * 未选择银行异常
     */
    public static final TransactionException NOT_SELECT_BANK = new TransactionException(
            "error.inpour.not_select_bank");

    /**
     * 未通过身份证认证异常
     */
    public static final TransactionException UNPASS_IDCARD_AUTHENTICATION = new TransactionException(
            "error.draw.unpass_idcard_authentication");

    /**
     * 未进行过交易异常
     */
    public static final TransactionException NOT_TRANSACTED = new TransactionException(
            "error.draw.not_transacted");

    /**
     * 支付密码错误异常
     */
    public static final TransactionException PAY_PASSWORD_ERROR = new TransactionException(
            "error.transaction.pay_password_error");

    /**
     * 余额不足异常
     */
    public static final TransactionException LACK_OF_BALANCE = new TransactionException(
            "error.transaction.lack_of_balance");

    /**
     * 收款方收到的金额无效异常（<=0；收款方需要支付的手续费大于或等于收款金额）
     */
    public static final TransactionException CREDIT_RECEIVE_AMOUT_INVALID = new TransactionException(
            "error.transaction.credit_receive_amount_invalid");

    /**
     * 子账户不属于相同主账户异常
     */
    public static final TransactionException NOT_THE_SAME_ACCOUNT = new TransactionException(
            "error.sub_account.not_the_same_account");

    /**
     * 不存在的账户异常
     */
    public static final TransactionException UNEXISTED_ACCOUNT = new TransactionException(
            "error.account.unexisted");

    /**
     * 交易双方主账户相同的异常
     */
    public static final TransactionException THE_SAME_DEBIT_CREDIT = new TransactionException(
            "error.account.the_same_debit_credit");

    /**
     * 重复提交异常
     */
    public static final TransactionException REPEATEDLY_SUBMIT = new TransactionException(
            "error.transaction.repeatedly_submit");

    /**
     * 批量支付未设置交易对方账户
     */
    public static final TransactionException NO_PEER_ACCOUNT = new TransactionException(
            "error.batch.no_peer_account");

    /**
     * 非企业用户不能进行的交易异常
     */
    public static final TransactionException ENTERPRISE_OPERATOR_LIMITED = new TransactionException(
            "error.account.enterprise_operator_limited");

    /**
     * 处于审核流程中的批量支付交易不能进行最终支付
     */
    public static final TransactionException BATCH_AUDITING_TRANS_CANNOT_PAY = new TransactionException(
            "error.batch.auditing_trans_cannot_pay");

    /**
     * 批量支付中没有待支付交易
     */
    public static final TransactionException BATCH_NO_TRANS_WAITING_PAY = new TransactionException(
            "error.batch.no_trans_waiting_pay");

    /**
     * 查询请求缺少必要的参数
     */
    public static final TransactionException INVALID_QUERY_PARAMETER = new TransactionException(
            "error.transaction.invalid_query_parameter");

    /**
     * 企业用户没有向个人用户支付的权限
     */
    public static final TransactionException B2C_NOTAVAIABLE = new TransactionException(
            "error.transaction.b2c_notavaiable");

    /**
     * 前一步没有全部通过审核，本步骤不能进行审核
     */
    public static final TransactionException REQUIRED_ALL_AUDITED = new TransactionException(
            "error.transaction.required_all_audited");

    /**
     * 不支持提现的银行的异常
     */
    public static final TransactionException DRAW_UNSUPPORTED_BANK = new TransactionException(
            "error.draw.unsupported_bank");
    
    /**
     * 退款金额异常
     */
    public static final TransactionException RETURN_AMOUNT_ERR = new TransactionException(
    		"error.transaction.return_amount_err");

    public TransactionException(String code) {
        super(code);
    }

    public TransactionException(String code, Object arg) {
        super(code, arg);
    }

    public TransactionException(String code, Object[] args) {
        super(code, args);
    }

    public TransactionException(String code, Object[] args,
            String defaultMessage) {
        super(code, args, defaultMessage);
    }

    /**
     * 金额格式
     */
    private static final String AMOUNT_PATTERN = "#0.##";

    /**
     * 获取充值金额低于费率的异常
     * 
     * @param amount
     *            充值金额
     * @param fee
     *            费率
     * @return 充值金额低于费率的异常
     */
    public static final TransactionException getAmountUnderFeeException(
            double amount, double fee) {
        String amountValue = StringUtil.double2String(amount, AMOUNT_PATTERN);
        String feeValue = StringUtil.double2String(fee, AMOUNT_PATTERN);
        return new TransactionException("error.inpour.amount_under_fee",
                new Object[] { amountValue, feeValue });
    }

    /**
     * 支付密码错误，且当日累计输错次数小于或等于系统所允许的上限值异常
     */
    public static final TransactionException getPayPasswordError(
            String currentPayPwdErr, String maxPayPwdErr) {
        return new TransactionException(
                "error.transaction.pay_password_error_continue", new Object[] {
                        currentPayPwdErr, maxPayPwdErr });
    }

    /**
     * 支付密码错误，且当日累计输错次数大于系统所允许的上限值异常
     */
    public static final TransactionException getPayPasswordErrorNeedLogout(
            String maxPayPwdErr) {
        return new TransactionException(
                "error.transaction.pay_password_error_logout", maxPayPwdErr);
    }

    /**
     * 获取账户金额限制异常
     * 
     * @param account
     *            账户
     * @param accountLimit
     *            账户金额限制
     * @param amount
     *            本次交易金额
     * @return 账户金额限制异常
     */
    public static final TransactionException getAccountLimitException(
            Account account, AccountLimit accountLimit, double amount) {
        // String eachLimit =
        // StringUtil.double2String(accountLimit.getEachlimit()
        // .doubleValue(), AMOUNT_PATTERN);
        String allLimit = StringUtil.double2String(accountLimit.getAlllimit()
                .doubleValue(), AMOUNT_PATTERN);
        // String transCountPerDay =
        // String.valueOf(accountLimit.getTranamount());
        // String transCountToday = account.getTranAmount() == null ? "0" :
        // String
        // .valueOf(account.getTranAmount().intValue());
        String sumAmount = StringUtil.double2String(account.getSumAmount()
                .doubleValue(), AMOUNT_PATTERN);
        Object[] args = { allLimit, sumAmount,
                StringUtil.double2String(amount, AMOUNT_PATTERN) };
        return new TransactionException(
                "error.transaction.beyond_amount_limit", args);
    }

    /**
     * 获取账户不能进行交易的异常
     * 
     * @param account
     *            不能进行交易的账户
     * @return 账户不能进行交易的异常
     */
    public static final TransactionException getCannotTransactException(
            Account account) {
        return new TransactionException("error.account.cannot_transact",
                account.getName());
    }

    /**
     * 
     * @param e
     *            IOException
     * @return 加载批量导入文件数据时出现的IO异常
     */
    public static TransactionException getImportFileIOException(IOException e) {
        String message = "caused by IOException: " + e.getMessage();
        return new TransactionException("error.batch.import_file_io_exception",
                new Object[0], message);
    }

    /**
     * 获取已存在付款方订单编号交易的异常
     * 
     * @param debitAccount
     *            付款方账户
     * @param orderId
     *            订单编号
     * @return 已存在付款方订单编号交易的异常
     */
    public static TransactionException getExistedOrderIdException(
            Account debitAccount, String orderId) {
        String accountId = debitAccount.getAccountId();
        return new TransactionException(
                "error.transaction.debit_existed_orderId", new Object[] {
                        accountId, orderId });
    }

    /**
     * 获取不存在指定账户编号的账户异常
     * 
     * @param accountId
     *            账户编号
     * @return 不存在指定账户编号的账户异常
     */
    public static TransactionException getUnexistedAccountException(
            String accountId) {
        String message = "Account whose accountId is " + accountId
                + " is not existed.";
        return new TransactionException("error.account.accountId_not_exist",
                new Object[] { accountId }, message);
    }

    /**
     * 获取批量导入文件内容格式错误异常
     * 
     * @param fieldName
     *            字段名
     * @param fieldValue
     *            字段值
     * @return 批量导入文件内容格式错误异常
     */
    public static TransactionException getImportFileContentFormatException(
            String fieldName, String fieldValue) {
        String message = "The content of batch import file format has error: the value of "
                + fieldName + " is " + fieldValue;
        return new TransactionException(
                "error.batch.import_file_content_format_error", new Object[] {
                        fieldName, fieldValue }, message);
    }
}
